package com.fa4j.common.data.repository.handler;

import com.fa4j.common.base.model.BaseEnum;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;

public class BaseEnumTypeHandler<E extends BaseEnum> extends BaseTypeHandler<E> {

    private final Class<E> enumClass;

    public BaseEnumTypeHandler(Class<E> enumClass) {
        if (enumClass == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }
        this.enumClass = enumClass;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, parameter.getCode());
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return getByCode(rs.getString(columnName));
    }

    private E getByCode(String codeStr) {
        if (codeStr == null || codeStr.isEmpty())
            return null;
        if (enumClass.isEnum()) {
            Integer code = Integer.parseInt(codeStr);
            for (E e : enumClass.getEnumConstants()) {
                if (Objects.equals(code, e.getCode())) {
                    return e;
                }
            }
        }
        return null;
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return getByCode(rs.getString(columnIndex));
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return getByCode(cs.getString(columnIndex));
    }
}
